DOI Link: http://dx.doi.org/10.1021/acs.jpclett.0c01794
1. Loading individual images
2. Segment using ParticleSpy
3. Loading all the particles for each case
4. Plotting the results
This notebook presents the code corresponding to histograms in Figure 5
import hyperspy.api as hs
import ParticleSpy.api as ps
import os
t75_path = r'C:\Users\eha56862\Documents\TEM for NPLs-YH-MD\T75-final'
t150_path = r'C:\Users\eha56862\Documents\TEM for NPLs-YH-MD\T150'
t200_path = r'C:\Users\eha56862\Documents\TEM for NPLs-YH-MD\T200'
os.listdir(t150_path)
os.chdir(t150_path)
t150_dm3_files = []
for file in os.listdir(t150_path):
if file.endswith('dm3'):
t150_dm3_files.append(file)
t150_dm3_files
This opens a GUI for segmentation (see instructions here). We iterate through all the images and for each case save an h5 particles file with the outcome of the segmentation.
n = 10
data = hs.load(t150_path + '/' + t150_dm3_files[n])
print(t150_dm3_files[n])
ps.SegUI(data)
params = ps.parameters()
params.load()
particles = ps.ParticleAnalysis(data, params)
particles.plot_area()
import h5py
def save_plist(p_list,filename):
f = h5py.File(filename,'w')
for i, particle in enumerate(p_list.list):
p_group = f.create_group("Particle "+str(i))
p_group.attrs["Area"] = particle.properties['area']['value']
p_group.attrs["Area units"] = particle.properties['area']['units']
p_group.attrs["Equivalent circular diameter"] = particle.properties['equivalent circular diameter']['value']
p_group.attrs["Equivalent circular diameter units"] = particle.properties['equivalent circular diameter']['units']
p_group.attrs["X"] = particle.properties['x']['value']
p_group.attrs["X units"] = particle.properties['x']['units']
p_group.attrs["Y"] = particle.properties['y']['value']
p_group.attrs["Y units"] = particle.properties['y']['units']
p_group.attrs["Equivalent circular diameter"] = particle.properties['equivalent circular diameter']['units']
p_group.attrs["Major axis length"] = particle.properties['major axis length']['value']
p_group.attrs["Major axis length units"] = particle.properties['major axis length']['units']
p_group.attrs["Minor axis length"] = particle.properties['minor axis length']['value']
p_group.attrs["Minor axis length units"] = particle.properties['minor axis length']['units']
p_group.attrs["Circularity"] = particle.properties['circularity']['value']
p_group.attrs["Eccentricity"] = particle.properties['eccentricity']['value']
p_group.attrs["Solidity"] = particle.properties['solidity']['value']
p_group.attrs["Intensity"] = particle.properties['intensity']['value']
p_group.attrs["Intensity_max"] = particle.properties['intensity_max']['value']
p_group.attrs["Intensity_std"] = particle.properties['intensity_std']['value']
p_group.create_dataset("Mask",data=particle.mask)
if hasattr(particle, 'image'):
p_group.create_dataset("Image",data=particle.image.data)
f.close()
save_plist(particles, r'C:\Users\eha56862\Documents\TEM for NPLs-YH-MD\T150\im19.h5')
os.chdir(t75_path)
t75_h5_files = []
for file in os.listdir(t75_path):
if file.endswith('h5'):
t75_h5_files.append(file)
os.chdir(t150_path)
t150_h5_files = []
for file in os.listdir(t150_path):
if file.endswith('h5'):
t150_h5_files.append(file)
os.chdir(t200_path)
t200_h5_files = []
for file in os.listdir(t200_path):
if file.endswith('h5'):
t200_h5_files.append(file)
t200_h5_files
import h5py
from ParticleSpy.ptcl_class import Particle, Particle_list
import hyperspy as hs
import numpy as np
def load_plist(filename):
f = h5py.File(filename,'r')
p_list = Particle_list()
for p_name in list(f.keys()):
if p_name[:8] == 'Particle':
p_group = f[p_name]
particle = Particle()
particle.set_area(p_group.attrs['Area'],p_group.attrs['Area units'])
particle.set_circularity(p_group.attrs["Circularity"])
particle.set_circdiam(p_group.attrs["Equivalent circular diameter"],p_group.attrs["Equivalent circular diameter units"])
particle.set_axes_lengths([p_group.attrs["Major axis length"],p_group.attrs["Minor axis length"]],p_group.attrs["Major axis length units"])
particle.set_eccentricity(p_group.attrs["Eccentricity"])
particle.set_intensity(p_group.attrs["Intensity"])
particle.set_mask(np.array(p_group['Mask'][:]))
if "Image" in p_group:
particle.store_im(hs.signals.Signal2D(np.array(p_group['Image'][:])))
p_list.append(particle)
f.close()
return(p_list)
os.chdir(t75_path)
t75_particles = []
for file in t75_h5_files:
data = load_plist(file)
t75_particles.append(data)
os.chdir(t150_path)
t150_particles = []
for file in t150_h5_files:
data = load_plist(file)
t150_particles.append(data)
os.chdir(t200_path)
t200_particles = []
for file in t200_h5_files:
data = load_plist(file)
t200_particles.append(data)
t75_data_area = []
t75_data_circularity = []
for i, image in enumerate(t75_particles):
for particle in t75_particles[i].list:
t75_data_area.append(particle.properties['area']['value'])
t75_data_circularity.append(particle.properties['circularity']['value'])
t150_data_area = []
t150_data_circularity = []
for i, image in enumerate(t150_particles):
for particle in t150_particles[i].list:
t150_data_area.append(particle.properties['area']['value'])
t150_data_circularity.append(particle.properties['circularity']['value'])
t200_data_area = []
t200_data_circularity = []
for i, image in enumerate(t200_particles):
for particle in t200_particles[i].list:
t200_data_area.append(particle.properties['area']['value'])
t200_data_circularity.append(particle.properties['circularity']['value'])
print(len(t75_data_area), len(t150_data_area), len(t200_data_area))
data_area = [t75_data_area, t150_data_area, t200_data_area]
data_circularity = [t75_data_circularity, t150_data_circularity, t200_data_circularity]
import matplotlib.pyplot as plt
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(11,8))
data_names = ['75 C', '150 C', '200 C']
axes.hist(data_area, bins=20, range=(0, 200), density=True, rwidth=0.9, label=data_names)
axes.legend(prop={'size':20})
plt.xlabel('Area $nm^2$', fontsize=20)
plt.ylabel('Probability density', fontsize=20)
fig, axes = plt.subplots(nrows=1, ncols=1, figsize=(11,8))
data_names = ['75 C', '150 C', '200 C']
axes.hist(data_circularity, bins=20, density=True, rwidth=0.9, label=data_names)
axes.legend(prop={'size':20})
plt.xlabel('Circularity', fontsize=20)
plt.ylabel('Probability density', fontsize=20)
def circularity(particle_area , particle_perimeter):
return (4*np.pi*particle_area)/(particle_perimeter**2)
r = 1
print('Circularity of a perfect circle:', circularity(np.pi * (r**2), 2*np.pi*r))
print('Circularity of a perfect square:', circularity((r**2), 4*r))